<template>
  <section class="my-table">
    <el-table
      :data="tableData"
      ref="tableRef"
      fit
      max-height="380"
      border
      stripe
      size="mini"
      cell-class-name="word-h"
    >
      <af-table-column
        prop="date"
        label="必要元素："
        align="center"
       
        fixed="left"
        width="100"
      >
      </af-table-column>
      <el-table-column type="selection" width="55"> </el-table-column>
      <af-table-column
        prop="name"
        label="class不能为【myTable】"
        min-width="180"
        align="center"
       
      >
      </af-table-column>
      <af-table-column
        prop="province"
        label="省份"
        min-width="150"
        align="center"
      >
      </af-table-column>
      <af-table-column prop="city" label="市区" min-width="150" align="center">
        <template>
          <el-tooltip
            class="item"
            effect="dark"
            content="1"
            placement="top-start"
          >
            <el-button size="mini">上左</el-button>
          </el-tooltip>
        </template>
      </af-table-column>
      <af-table-column
        prop="address"
        label="地址"
        min-width="150"
        align="center"
      >
      </af-table-column>
      <af-table-column label="操作" min-width="160" align="center">
        <template>
          <el-button size="mini">编辑</el-button>
          <el-button size="mini" type="danger">删除</el-button>
        </template>
      </af-table-column>
    </el-table>
  </section>
</template>
  
  <script>
export default {
  name: "MyTable",
  data() {
    return {
      tableData: [], // 需要渲染的数据
      saveDATA: [], // 所有数据
      tableRef: null, // 设置了滚动的那个盒子
      tableWarp: null,
      fixLeft: null,
      fixRight: null,
      tableFixedLeft: null,
      tableFixedRight: null,
      scrollTop: 0,
      num: 0,
      start: 0,
      end: 42, // 3倍的pageList
      starts: 0, // 备份[保持与上一样]
      ends: 42, // 备份[保持与上一样]
      pageList: 14, // 一屏显示
      itemHeight: 33, // 每一行高度
      timeOut: 400, // 延迟
    };
  },
  watch: {
    num: function (newV) {
      // 因为初始化时已经添加了3屏的数据，所以只有当滚动到第3屏时才计算位移量
      if (newV > 1) {
        this.start = (newV - 1) * this.pageList;
        this.end = (newV + 2) * this.pageList;
        // 使用延时器会造成页面短暂白屏的问题，使用requestAnimationFrame则可以解决
        // setTimeout(() => {
        // // 计算偏移量
        //   this.tableWarp.style.transform = `translateY(${this.start *
        //     this.itemHeight}px)`
        //   if (this.fixLeft) {
        //     this.fixLeft.style.transform = `translateY(${this.start *
        //       this.itemHeight}px)`
        //   }
        //   if (this.fixRight) {
        //     this.fixRight.style.transform = `translateY(${this.start *
        //       this.itemHeight}px)`
        //   }
        //   this.tableData = this.saveDATA.slice(this.start, this.end)
        // }, this.timeOut)
        requestAnimationFrame(() => {
          // 计算偏移量
          this.tableWarp.style.transform = `translateY(${
            this.start * this.itemHeight
          }px)`;
          if (this.fixLeft) {
            this.fixLeft.style.transform = `translateY(${
              this.start * this.itemHeight
            }px)`;
          }
          if (this.fixRight) {
            this.fixRight.style.transform = `translateY(${
              this.start * this.itemHeight
            }px)`;
          }
          this.tableData = this.saveDATA.slice(this.start, this.end);
        });
      } else {
        requestAnimationFrame(() => {
          this.tableData = this.saveDATA.slice(this.starts, this.ends);
          this.tableWarp.style.transform = `translateY(0px)`;
          if (this.fixLeft) {
            this.fixLeft.style.transform = `translateY(0px)`;
          }
          if (this.fixRight) {
            this.fixRight.style.transform = `translateY(0px)`;
          }
        });
        // setTimeout(() => {
        //   this.tableData = this.saveDATA.slice(this.starts, this.ends)
        //   this.tableWarp.style.transform = `translateY(0px)`
        //   if (this.fixLeft) {
        //     this.fixLeft.style.transform = `translateY(0px)`
        //   }
        //   if (this.fixRight) {
        //     this.fixRight.style.transform = `translateY(0px)`
        //   }
        // }, this.timeOut)
      }
    },
    data(valArr) {
      const _this = this;
      this.formThead = fields.map(function (value) {
        const arr = valArr.map((x) => x[value.prop]); // 获取每一列的所有数据
        arr.push(value.label); // 把每列的表头也加进去算
        value.width = _this.getMaxLength(arr) + 20; // 每列内容最大的宽度 + 表格的内间距(依据实际情况而定)
        return value;
      });
    },
  },
  created() {
    this.init();
  },
  mounted() {
    this.$nextTick(() => {
      // 设置了滚动的盒子
      this.tableRef = this.$refs.tableRef.bodyWrapper;
      // 左侧固定列所在的盒子
      this.tableFixedLeft = document.querySelector(
        ".el-table .el-table__fixed .el-table__fixed-body-wrapper"
      );
      // 右侧固定列所在的盒子
      this.tableFixedRight = document.querySelector(
        ".el-table .el-table__fixed-right .el-table__fixed-body-wrapper"
      );
      /**
       * fixed-left | 主体 | fixed-right
       */
      // 主体改造
      // 创建内容盒子divWarpPar并且高度设置为所有数据所需要的总高度
      let divWarpPar = document.createElement("div");
      // 如果这里还没获取到saveDATA数据就渲染会导致内容盒子高度为0，可以通过监听saveDATA的长度后再设置一次高度
      divWarpPar.style.height = this.saveDATA.length * this.itemHeight + "px";
      // 新创建的盒子divWarpChild
      let divWarpChild = document.createElement("div");
      divWarpChild.className = "fix-warp";
      // 把tableRef的第一个子元素移动到新创建的盒子divWarpChild中
      divWarpChild.append(this.tableRef.children[0]);
      // 把divWarpChild添加到divWarpPar中，最把divWarpPar添加到tableRef中
      divWarpPar.append(divWarpChild);
      this.tableRef.append(divWarpPar);

      // left改造
      let divLeftPar = document.createElement("div");
      divLeftPar.style.height = this.saveDATA.length * this.itemHeight + "px";
      let divLeftChild = document.createElement("div");
      divLeftChild.className = "fix-left";
      this.tableFixedLeft &&
        divLeftChild.append(this.tableFixedLeft.children[0]);
      divLeftPar.append(divLeftChild);
      this.tableFixedLeft && this.tableFixedLeft.append(divLeftPar);

      // right改造
      let divRightPar = document.createElement("div");
      divRightPar.style.height = this.saveDATA.length * this.itemHeight + "px";
      let divRightChild = document.createElement("div");
      divRightChild.className = "fix-right";
      this.tableFixedRight &&
        divRightChild.append(this.tableFixedRight.children[0]);
      divRightPar.append(divRightChild);
      this.tableFixedRight && this.tableFixedRight.append(divRightPar);

      // 被设置的transform元素
      this.tableWarp = document.querySelector(
        ".el-table .el-table__body-wrapper .fix-warp"
      );
      this.fixLeft = document.querySelector(
        ".el-table .el-table__fixed .el-table__fixed-body-wrapper .fix-left"
      );
      this.fixRight = document.querySelector(
        ".el-table .el-table__fixed-right .el-table__fixed-body-wrapper .fix-right"
      );

      this.tableRef.addEventListener("scroll", this.onScroll);
    });
  },
  methods: {
    init() {
      this.saveDATA = [];
      for (let i = 0; i < 10000; i++) {
        this.saveDATA.push({
          date: i,
          name:
            "王小虎王小虎王小虎王小虎王小虎王小虎王小虎王小虎王小虎王小虎王小虎" +
            i,
          address: "1518",
          province: "github:",
          city: "divcssjs",
          zip: "divcssjs" + i,
        });
      }
      this.tableData = this.saveDATA.slice(this.start, this.end);
    },
    getMaxLength(arr) {
      return arr.reduce((acc, item) => {
        if (item) {
          let calcLen = this.getTextWidth(item);
          if (acc < calcLen) {
            acc = calcLen;
          }
        }
        return acc;
      }, 0);
    },
    /**
     * 使用span标签包裹内容，然后计算span的宽度 width： px
     * @param valArr
     */
    getTextWidth(str) {
      let width = 0;
      let html = document.createElement("span");
      html.innerText = str;
      html.className = "getTextWidth";
      document.querySelector("body").appendChild(html);
      width = document.querySelector(".getTextWidth").offsetWidth;
      document.querySelector(".getTextWidth").remove();
      return width;
    },
    onScroll() {
      this.scrollTop = this.tableRef.scrollTop;
      this.num = Math.floor(this.scrollTop / (this.itemHeight * this.pageList));
    },
  },
};
</script>
  <style lang="css">
.el-table--mini .el-table__cell {
  padding: 2px 0 !important;
}
.ceil {
  max-height: 25px;
}
.word-h div {
  word-break: keep-all !important;
}
.my-table .el-table__fixed-body-wrapper {
  width: 100%;
}


/*滚动条样式*/
</style>
  
  
  